package com.softserveinc.ita.kaiji.multiplay.domain.room;

import com.softserveinc.ita.kaiji.multiplay.domain.card.Card;
import com.softserveinc.ita.kaiji.multiplay.domain.card.Deck;
import com.softserveinc.ita.kaiji.multiplay.domain.config.ShipConfigForGame;
import com.softserveinc.ita.kaiji.multiplay.domain.message.InOutMessage;
import com.softserveinc.ita.kaiji.multiplay.domain.player.PlayerOnlineInfo;
import com.softserveinc.ita.kaiji.multiplay.domain.player.ShipPlayer;
import com.softserveinc.ita.kaiji.multiplay.domain.table.ShipTable;
import com.softserveinc.ita.kaiji.multiplay.dto.server.room.DtoShip;

/**
 * Project kaiji-game
 * Created by mikeldpl
 * 25.03.2015 14:03.
 */
public class Ship extends PlayRoom {

	private final ShipConfigForGame conf;
	private final Deck deck;
	private final ShipTables tables;

	public Ship(ShipConfigForGame configForGame) {
		super(configForGame);
		conf = configForGame;
		deck = new Deck(configForGame.getNumberOfCardsOneTypeConfig() * configForGame.getMaxNumberOfPlayersConfig(),
				conf.getNumberOfCardsTypesConfig());
		tables = new ShipTables(this, conf.getNumberOfTablesConfig());
	}

	//------------------------------------------------------------------------------cards
	public int decreaseCard(InOutMessage msg, Card card) {
		int numberOfCard = deck.decreaseCard(card);
		msg.addDomainThatMustBeSanded(this);
		return numberOfCard;
	}

	public void setNumberCard(InOutMessage msg, Card card, int n) {
		deck.setNumberOfCards(card, n);
		msg.addDomainThatMustBeSanded(this);
	}

	//----------------------------------------------------------------------------------add and start
	@Override
	public synchronized boolean addPlayer(PlayerOnlineInfo info) { // This method will have to be removed in the future
		if (super.addPlayer(info)) {
			InOutMessage msg = new InOutMessage(null, null);
			for (ShipTable shipTable : getTables().getTables()) {
				shipTable.addSubscriber(info);
				msg.addDomainThatMustBeSanded(shipTable);
			}
			msg.sendResponse();
			return true;
		}
		return false;
	}
	//	private void recalculateDeck(InOutMessage msg){
//		Iterator<ShipPlayer> iterator = (Iterator)getPlayers().getPlayers().iterator();
//		while (iterator.hasNext()){
//
//		}
//	}

	@Override
	public void clear(InOutMessage msg) {
		super.clear(msg);
		for (Card card : getDeck().getDeck().keySet()) {
			getDeck().getDeck().put(card, 0);
		}
		for (ShipTable shipTable : getTables().getTables()) {
			shipTable.sitOut(msg);
		}
	}

	//------------------------------------------------------------------------------------------------------core

	@Override
	public void processMessage(InOutMessage message) {
		if (getState() == StateOfRoom.GAME) {
			switch (message.getIn().getType()) {
				case TABLE:
					getTables().getById(Integer.parseInt(message.getIn().getName())).processMessage(message);
					message.addDomainThatMustBeSanded(this);
					break;
				case PLAYER:
					message.getPlayer().processMessage(message);
					break;
			}
		}
	}

	//------------------------------------------------------------------------------------------------------
	@Override
	public ShipPlayer getNewPlayer(String name) {
		return new ShipPlayer(name, this, conf.getPlayerNumberOfStart(), conf.getNumberOfCardsOneTypeConfig(),
				conf.getNumberOfCardsTypesConfig());
	}

	@Override
	public DtoShip getDto() {
		return new DtoShip(getName());
	}

	@Override
	public DtoShip getEntireDto() {
		DtoShip entireDto = (DtoShip) super.getEntireDto();
		entireDto.getDeck().putAll(deck.getMapStToInt());
		return entireDto;
	}

	//-------------------------------------------------getters

	public ShipTables getTables() {
		return tables;
	}

	public Deck getDeck() {
		return deck;
	}

	public ShipConfigForGame getConf() {
		return conf;
	}
}
